#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "js.h"

static JS *s_js;

extern void js_dump(JS *js);

static char* root_path = NULL;

// Function that loads JS code from a given file.
static jsval_t require(const char *filename) {
  char data[32 * 1024];
  strcat(root_path, filename);

  printf("src file ====> %s \r\n", root_path);

  FILE *fp = fopen(root_path, "rb");
  if (fp == NULL) return 0;
  size_t len = fread(data, 1, sizeof(data), fp);
  return js_eval(s_js, data, len);
}

static jsval_t eval(const char *code) {
  return js_eval(s_js, code, ~0);
}

static void print(const char *str) {
  printf("%s", str);
}

static const char *str(jsval_t v) {
  return js_str(s_js, v);
}

int main(int argc, char *argv[]) {
  char mem[8192];
  JS *js = s_js = js_create(mem, sizeof(mem));
  printf("===============> %ud\r\n", (unsigned int)sizeof(mem));

  root_path = malloc(200);
  memset(root_path, 0, 200);
  getcwd(root_path, 200);
  strcat(root_path, "/");
  printf("current working directory : %s\n", root_path);

  const char *code = argc > 1 ? argv[1] : "";
  printf("code -------------------->>>>: %s \r\n", code);
  if( argc > 2 ) {
      char *arg_key = NULL;
      char *arg_value = NULL;

      for(int i = 1; i < argc; i += 2) {
          arg_key = argv[i];
          arg_value = argv[i + 1];

          if( !strcmp(arg_key, "-e") ) {
              code = arg_value;
          } else if( !strcmp(arg_key, "-f") ) {
              strcat(root_path, arg_value);
          }
      }
  }

  printf("code -------------------->>>: %s \r\n", code);

  if (root_path == NULL)
    return -1;

  clock_t beginning = clock();
  jsval_t res = js_eval(js, "undefined", ~0);
  int i, verbose = 0;

  // Import our custom function "require" into the global namespace.
  js_set(js, js_glob(js), "require", js_import(js, (uintptr_t) require, "js")); // j表示最终返回值是一个js对象 m表示第一个参数是整数，s表示第二个参数是字符串
  js_set(js, js_glob(js), "print", js_import(js, (uintptr_t) print, "vs")); // v表示返回值undefined s表示字符串
  js_set(js, js_glob(js), "eval", js_import(js, (uintptr_t) eval, "js"));
  js_set(js, js_glob(js), "str", js_import(js, (uintptr_t) str, "sj"));
  // jsval_t res = js_eval(js, code, strlen(code));

  // Process command line args
  for (i = 1; i < argc; i++) {
    if (strcmp(argv[i], "-v") == 0) {
      verbose++;
    } else if (strcmp(argv[i], "-e") == 0 && i + 1 < argc) {
      res = js_eval(js, argv[++i], ~0);
    } else {
      printf("Usage: %s [-v] [-e EXPRESSION] ...\r\n", argv[0]);
    }
  }

  printf("%s\n", js_str(js, res));

  js_dump(js);

  if (verbose) {
    double ms = (double) (clock() - beginning) * 1000 / CLOCKS_PER_SEC;
    printf("Executed in %g ms. Mem usage is %d%% of %d bytes.\n", ms, js_usage(js), (int) sizeof(mem));
  }

  free(root_path);
  root_path = NULL;
  return EXIT_SUCCESS;
}
